package com.pactera.madp.cp.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pactera.madp.common.core.exception.CheckedException;
import com.pactera.madp.common.security.util.SecurityUtils;
import com.pactera.madp.cp.api.dto.workcontacttag.WorkContactTagGroupAddDTO;
import com.pactera.madp.cp.api.dto.workcontacttag.WorkContactTagGroupUpdateDTO;
import com.pactera.madp.cp.api.em.workupdatetime.TypeEnum;
import com.pactera.madp.cp.api.entity.BaseEntity;
import com.pactera.madp.cp.api.entity.WorkContactTagEntity;
import com.pactera.madp.cp.api.entity.WorkContactTagGroupEntity;
import com.pactera.madp.cp.api.entity.WorkContactTagPivotEntity;
import com.pactera.madp.cp.api.page.SubPage;
import com.pactera.madp.cp.api.vo.ContactTagGroupPageVO;
import com.pactera.madp.cp.api.vo.ContactTagVO;
import com.pactera.madp.cp.api.vo.contact.ContactTagGroupIndexVO;
import com.pactera.madp.cp.handler.CorpContextHolder;
import com.pactera.madp.cp.mapper.WorkContactTagGroupMapper;
import com.pactera.madp.cp.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: yangpengwei
 * @time: 2020/12/14 5:32 下午
 * @description 客户标签组 service
 */
@Slf4j
@Service
@Transactional(rollbackFor = {RuntimeException.class, Exception.class})
public class WorkContactTagGroupServiceImp extends ServiceImpl<WorkContactTagGroupMapper, WorkContactTagGroupEntity> implements IWorkContactTagGroupService {

    @Autowired
    private WorkContactTagGroupMapper workContactTagGroupMapper;
    @Autowired
    private IWorkContactTagService workContactTagService;
    @Resource
    private IWorkEmployeeService employeeService;
    @Autowired
    private IWorkUpdateTimeService workUpdateTimeService;
    @Autowired
    IWorkContactTagPivotService iWorkContactTagPivotService;
    @Autowired
    private IWorkContactTagPivotService contactTagPivotService;

    @Override
    public Page<List<ContactTagGroupPageVO>> getGroupList(Page page) {
        int corpId = CorpContextHolder.getCorpId();
        IPage iPage = this.baseMapper.selectMapsPage(page, new QueryWrapper<WorkContactTagGroupEntity>()
                .select("id", "group_name", "create_name","type")
                .eq("corp_id", corpId).orderByDesc("create_time"));
        List<Map<String,String>> records = iPage.getRecords();
        List<ContactTagGroupPageVO> voList = new ArrayList<>();

        for (int i = 0; i < records.size(); i++) {
            Integer id = Integer.valueOf(String.valueOf(records.get(i).get("id")));
            ContactTagGroupPageVO vo = new ContactTagGroupPageVO();
            vo.setGroupId(id);
            vo.setGroupName(records.get(i).get("group_name"));
            vo.setCreateName(records.get(i).get("create_name"));
            vo.setType(records.get(i).get("type"));
            List<ContactTagVO> allTag = workContactTagService.getAllTag(id,corpId);
            List<String> list = new LinkedList<>();
            for (ContactTagVO c:allTag) {
                list.add(c.getName());
            }
            vo.setTagNameList(list);
            voList.add(vo);
        }
        SubPage subPage = new SubPage();
        subPage.setRecords(voList);
        subPage.setCurrent(iPage.getCurrent());
        subPage.setSize(iPage.getSize());
        subPage.setTotal(iPage.getTotal());
        Map<String, Object> map = new HashMap<>();
        map.put("syncTagTime",workUpdateTimeService.getLastUpdateTime(TypeEnum.TAG));
        subPage.setExtraProps(map);
        return subPage;
    }

    @Override
    public List<ContactTagGroupIndexVO> getIndexList() {
        List<WorkContactTagGroupEntity> entities = this.baseMapper.selectList(Wrappers.<WorkContactTagGroupEntity>lambdaQuery()
                .select(WorkContactTagGroupEntity::getId, WorkContactTagGroupEntity::getGroupName, WorkContactTagGroupEntity::getCreateName)
                .eq(WorkContactTagGroupEntity::getCorpId, CorpContextHolder.getCorpId())
                .orderByDesc(BaseEntity::getCreateTime));
        List<ContactTagGroupIndexVO> indexVOS = new LinkedList<>();
        for (WorkContactTagGroupEntity e:entities) {
            ContactTagGroupIndexVO vo = new ContactTagGroupIndexVO();
            vo.setGroupId(e.getId());
            vo.setGroupName(e.getGroupName());
            vo.setCreateName(e.getCreateName());
            List<ContactTagVO> allTag = workContactTagService.getAllTag(e.getId(),CorpContextHolder.getCorpId());
            vo.setTagNameList(allTag);
            indexVOS.add(vo);
        }
        return indexVOS;
    }

    @Override
    public List<ContactTagGroupIndexVO> getIndexListWeChat( Integer corpId) {
        List<WorkContactTagGroupEntity> entities = this.baseMapper.selectList(Wrappers.<WorkContactTagGroupEntity>lambdaQuery()
                .select(WorkContactTagGroupEntity::getId, WorkContactTagGroupEntity::getGroupName, WorkContactTagGroupEntity::getCreateName,WorkContactTagGroupEntity::getType)
                .eq(WorkContactTagGroupEntity::getCorpId, corpId)
                .orderByDesc(WorkContactTagGroupEntity::getCreateTime));
        List<ContactTagGroupIndexVO> indexVOS = new LinkedList<>();
        for (WorkContactTagGroupEntity e:entities) {
            //去除系统标签
            if (e.getType().equals("1")) {
                continue;
            }
            ContactTagGroupIndexVO vo = new ContactTagGroupIndexVO();
            vo.setGroupId(e.getId());
            vo.setGroupName(e.getGroupName());
            vo.setCreateName(e.getCreateName());
            List<ContactTagVO> allTag = workContactTagService.getAllTag(e.getId(),corpId);
            vo.setTagNameList(allTag);
            indexVOS.add(vo);
        }
        return indexVOS;
    }

    @Override
    public ContactTagGroupPageVO getGroupDetail(Integer groupTagId) {
        WorkContactTagGroupEntity entity = new WorkContactTagGroupEntity();
        entity.setId(groupTagId);
        entity = workContactTagGroupMapper.selectOne(new QueryWrapper<>(entity));

        if (entity == null) {
            throw new CheckedException("标签组不存在");
        }

        ContactTagGroupPageVO vo = new ContactTagGroupPageVO();
        vo.setGroupId(entity.getId());
        vo.setGroupName(entity.getGroupName());

        return vo;
    }

    @Override
    public boolean deleteGroup(Integer groupTagId) {
        if (groupTagId == null) {
            throw new CheckedException("groupId 不能为空");
        }

        WorkContactTagGroupEntity entity = new WorkContactTagGroupEntity();
        entity.setId(groupTagId);
        entity = workContactTagGroupMapper.selectOne(new QueryWrapper<>(entity));

        workContactTagGroupMapper.deleteById(entity.getId());
        //获取该标签分组下全部标签信息
        List<WorkContactTagEntity> list = workContactTagService.list(Wrappers.<WorkContactTagEntity>lambdaQuery().eq(WorkContactTagEntity::getContactTagGroupId, groupTagId));
       //删除标签组时，所有个人绑定的该标签组下标签信息全部删除
        list.forEach(workContactTagEntity -> {
            iWorkContactTagPivotService.remove(Wrappers.<WorkContactTagPivotEntity>lambdaQuery().eq(WorkContactTagPivotEntity::getContactTagId,workContactTagEntity.getId()));
        });
        if (workContactTagService.list(Wrappers.<WorkContactTagEntity>lambdaQuery().eq(WorkContactTagEntity::getContactTagGroupId,groupTagId)).isEmpty()){
            return true;
        }
        return workContactTagService.remove(Wrappers.<WorkContactTagEntity>lambdaQuery()
                .eq(WorkContactTagEntity::getContactTagGroupId,groupTagId));
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public boolean createGroup(WorkContactTagGroupAddDTO addDTO) {
        HashSet<String> set = new HashSet<>(addDTO.getTagNameList());
        if (set.size() != addDTO.getTagNameList().size()){
            throw new CheckedException("标签不能重复");
        }
        WorkContactTagGroupEntity one = getOne(Wrappers.<WorkContactTagGroupEntity>lambdaQuery()
                .eq(WorkContactTagGroupEntity::getGroupName, addDTO.getGroupName()));
        if (one != null){
            throw new CheckedException("标签分组名不能重复");
        }
        int corpId = CorpContextHolder.getCorpId();
        WorkContactTagGroupEntity entity = new WorkContactTagGroupEntity();
        entity.setCorpId(corpId);
        entity.setGroupName(addDTO.getGroupName());
        entity = workContactTagGroupMapper.selectOne(new QueryWrapper<>(entity));
        int insert;
        if (entity != null) {
            throw new CheckedException("标签组已存在");
        } else {
            entity = new WorkContactTagGroupEntity();
            entity.setCorpId(corpId);
            entity.setGroupName(addDTO.getGroupName());
            entity.setCreateName(SecurityUtils.getUser().getUsername());
            entity.setCreateTime(DateUtil.toLocalDateTime(new Date()));
            insert = workContactTagGroupMapper.insert(entity);
        }
        WorkContactTagGroupEntity selectOne = workContactTagGroupMapper.selectOne(
                new QueryWrapper<WorkContactTagGroupEntity>().eq("group_name", addDTO.getGroupName()));
        if (insert == 1){
            if (addDTO.getTagNameList() == null){
                return true;
            }
            ArrayList<WorkContactTagEntity> tagList = new ArrayList<>();
            addDTO.getTagNameList().forEach(tagName->{
                WorkContactTagEntity tagEntity = new WorkContactTagEntity();
                tagEntity.setWxContactTagId(null);
                tagEntity.setCorpId(selectOne.getCorpId());
                tagEntity.setName(tagName);
                tagEntity.setOrder(0);
                tagEntity.setContactTagGroupId(selectOne.getId());
                tagList.add(tagEntity);
            });
            return workContactTagService.saveBatch(tagList);

        }
        return false;
    }

    @Override
    public boolean updateGroup(WorkContactTagGroupUpdateDTO updateDTO) {
        HashSet<String> set = new HashSet<>(updateDTO.getTagNameList());
        if (set.size() != updateDTO.getTagNameList().size()){
            throw new CheckedException("标签不能重复");
        }

        WorkContactTagGroupEntity selectById = this.baseMapper.selectById(updateDTO.getGroupId());

        WorkContactTagGroupEntity entity = new WorkContactTagGroupEntity();
        entity.setId(updateDTO.getGroupId());
        entity = workContactTagGroupMapper.selectOne(new QueryWrapper<>(entity));
        if (entity == null) {
            throw new CheckedException("标签组id不存在");
        }

        entity.setGroupName(selectById.getGroupName());
        workContactTagGroupMapper.updateById(entity);

        WorkContactTagGroupEntity tagGroupEntity = this.getById(updateDTO.getGroupId());
        List<WorkContactTagEntity> tagEntities = workContactTagService.list(
                new QueryWrapper<WorkContactTagEntity>().eq("contact_tag_group_id", updateDTO.getGroupId()));
        List<String> list = updateDTO.getTagNameList();
        List<String> strings = new LinkedList<>();
        LinkedList<WorkContactTagEntity> entities = new LinkedList<>();
        for (WorkContactTagEntity tag:tagEntities) {
            for (String l:list) {
                if (tag.getName().equals(l)){
                    strings.add(l);
                    entities.add(tag);
                }
            }
        }
        list.removeAll(strings);
        tagEntities.removeAll(entities);
        if (list.size() != 0) {
            //需新增的标签列表
            ArrayList<WorkContactTagEntity> addedTagList = new ArrayList<>();
            list.forEach(tagName->{
                WorkContactTagEntity tagEntity = new WorkContactTagEntity();
                tagEntity.setWxContactTagId(null);
                tagEntity.setCorpId(tagGroupEntity.getCorpId());
                tagEntity.setName(tagName);
                tagEntity.setOrder(0);
                tagEntity.setContactTagGroupId(tagGroupEntity.getId());
                addedTagList.add(tagEntity);
            });
            workContactTagService.saveBatch(addedTagList);
        }

        //需删除的标签列表
        for (WorkContactTagEntity tag:tagEntities) {
            deleteTagAndPivotByTagId(tag.getId());
        }
        return true;
    }

    @Override
    public void wxBackCreateTagGroup(int corpId, String wxTagGroupId) {
        workContactTagService.synContactTag(corpId);
    }

    @Override
    public void wxBackUpdateTagGroup(int corpId, String wxTagGroupId) {
        workContactTagService.synContactTag(corpId);
    }

    @Override
    public void wxBackDeleteTagGroup(int corpId, String wxTagGroupId) {
        WorkContactTagGroupEntity entity = new WorkContactTagGroupEntity();
        entity.setWxGroupId(wxTagGroupId);
        entity.setCorpId(corpId);
        entity = workContactTagGroupMapper.selectOne(new QueryWrapper<>(entity));
        if (entity == null) {
            throw new CheckedException("标签组不存在");
        }
        workContactTagService.deleteTagByGroupId(corpId, entity.getId(), false);
        workContactTagGroupMapper.deleteById(entity.getId());
    }


    /**
     * 删除客户标签并删除客户标签与客户关联数据
     */
    public void deleteTagAndPivotByTagId(int tagId) {
        List<Integer> contactTagPivotIdList = contactTagPivotService.lambdaQuery()
                .select(WorkContactTagPivotEntity::getId)
                .eq(WorkContactTagPivotEntity::getContactTagId, tagId)
                .list()
                .stream()
                .map(WorkContactTagPivotEntity::getId)
                .collect(Collectors.toList());
        if (!contactTagPivotIdList.isEmpty()) {
            contactTagPivotService.removeByIds(contactTagPivotIdList);
        }
        workContactTagService.removeById(tagId);
    }
}
